package org.liuwei.concucrent.base07;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * @see http://blog.csdn.net/zero__007/article/details/50571703#
 * @Description: TODO(描述该文件做什么)
 * @author wei.liu
 * @date 2016年5月12日 下午12:40:45
 * @version V1.0
 */
public class CompletableFutureTest2 {
	private static ExecutorService executor = Executors.newFixedThreadPool(5);

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		testFuture();
	}

	// 对于Future可以这样提交任务：
	private static void testFuture() throws InterruptedException, ExecutionException {

		Future<String> result = executor.submit(() -> {
			TimeUnit.SECONDS.sleep(3);
			return "hello";
		});
		System.out.println(11111);
		System.out.println(result.get());
		System.out.println(3333);
	}

	// 使用CompletableFuture：
	@SuppressWarnings("unused")
	private static void testCompletableFuture() throws InterruptedException, ExecutionException {

		CompletableFuture<String> resultCompletableFuture = CompletableFuture.supplyAsync(new Supplier<String>() {
			@Override
			public String get() {
				try {
					TimeUnit.SECONDS.sleep(3);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return "hello";
			}
		}, executor);
		System.out.println(11111);
		System.out.println(resultCompletableFuture.get());
		System.out.println(3333);
	}

	// 上面testCompletableFuture()和Future的get()调用都会阻塞，
	// 但是可以CompletableFuture注册类似一个回调函数去处理结果：
	@SuppressWarnings("unused")
	private static void testCompletableFuture2() throws InterruptedException, ExecutionException {
		CompletableFuture<String> resultCompletableFuture = CompletableFuture.supplyAsync(new Supplier<String>() {
			@Override
			public String get() {
				try {
					TimeUnit.SECONDS.sleep(1);
					System.out.println(Thread.currentThread().getName());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return "hello";
			}
		}, executor);
		System.out.println(resultCompletableFuture.thenAccept(new Consumer<String>() {
			@Override
			public void accept(String t) {
				System.out.println(t);
				System.out.println(Thread.currentThread().getName());
			}
		}));
		System.out.println(123);
	}

	// 在testCompletableFuture2()注册的回调函数的执行与其提交的任务的执行是同一个线程完成的。
	// 如果不想同一个线程来完成回调函数，可以这样：
	@SuppressWarnings("unused")
	private static void testCompletableFuture3() throws InterruptedException, ExecutionException {
		CompletableFuture<String> resultCompletableFuture = CompletableFuture.supplyAsync(new Supplier<String>() {
			@Override
			public String get() {
				try {
					TimeUnit.SECONDS.sleep(1);
					System.out.println(Thread.currentThread().getName());
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return "hello";
			}
		}, executor);
		resultCompletableFuture.thenAcceptAsync(new Consumer<String>() {
			@Override
			public void accept(String t) {
				System.out.println(t);
				System.out.println(Thread.currentThread().getName());
			}
		}, executor);
		System.out.println(123);
	}
}
